package com.wfk.service.impl;

import com.wfk.constant.Constant;
import com.wfk.entity.Account;
import com.wfk.entity.Customer;
import com.wfk.entity.Goods;
import com.wfk.entity.MoneyDetails;
import com.wfk.entity.OrderGoods;
import com.wfk.enums.HandleType;
import com.wfk.enums.OrderStatusEnums;
import com.wfk.exception.ServiceException;
import com.wfk.mapper.AccountMapper;
import com.wfk.service.IAccountService;
import com.wfk.service.ICustomerService;
import com.wfk.service.IGoodsService;
import com.wfk.service.IMoneyDetailsService;
import com.wfk.service.IOrderGoodsService;
import com.wfk.utils.FunctionUtils;
import com.wfk.utils.ResponseData;
import com.wfk.utils.ValidateUtil;

import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

/**
 * <p>
 * 用户账户表 服务实现类
 * </p>
 *
 * @since 2019-01-07
 */
@Service
public class AccountServiceImpl extends ServiceImpl<AccountMapper, Account> implements IAccountService {
	private Lock lock = new ReentrantLock() ;
	@Autowired
	private IMoneyDetailsService moneyDetailsService ;
	@Autowired
	private ICustomerService customerService;
	@Autowired
	private IGoodsService goodsService;
	@Autowired
	private IOrderGoodsService orderGoodsService;
	@Override
	public String insertAccountDetail(Integer cid, Integer typeid, Integer isout, BigDecimal cost,String remark) {
		String result="";
		try {
			lock.lock();
			Account merchantAccount = super.getOne(new QueryWrapper<Account>().eq("cid",cid));
			BigDecimal originalPoint=merchantAccount.getMoney();
			BigDecimal point=merchantAccount.getMoney();
			if(FunctionUtils.isEquals(Constant.pay_in,isout)){
				point=FunctionUtils.add(point,cost, 2);
				if(ValidateUtil.isEquals(typeid,HandleType.brush.getId())) {
					merchantAccount.setSearchMoney(FunctionUtils.sub(merchantAccount.getSearchMoney(), cost, 2));
					merchantAccount.setAllMoney(FunctionUtils.add(merchantAccount.getAllMoney(),cost,2));
					merchantAccount.setDayMoney(FunctionUtils.add(merchantAccount.getDayMoney(),cost,2));
				}
			}else{
				point=FunctionUtils.sub(point,cost, 2);
				if(BigDecimal.ZERO.compareTo(point)>0) {
					return "余额不足";
				}
			}
			merchantAccount.setMoney(point);
			//首先修改积分 根据当前版本号去修改
			boolean i = super.updateById(merchantAccount) ;
			if(!i) {
				throw new ServiceException("更新会员金额异常") ;
			}
			MoneyDetails details = new MoneyDetails();
			details.setCid(cid);
			details.setTypeid(typeid);
			details.setIsout(isout);
			details.setOriginal(originalPoint);
			details.setCost(cost);
			details.setLast(point);
			details.setRemark(remark);
			i = moneyDetailsService.save(details);
			if(!i) {
				throw new ServiceException("添加商户金额明细失败") ;
			}
		} catch (Exception e) {
			e.printStackTrace();
			throw new ServiceException("保存校验用户金额异常");
		} finally {
			lock.unlock();
		}
		return result;
	}
	@Override
	public Account get(Integer cid) {
		QueryWrapper<Account> queryWrapper = new QueryWrapper<Account>();
		queryWrapper.eq("cid",cid);
		return super.getOne(queryWrapper);
	}
	@Override
	public ResponseData handleMoney(Integer cid, Integer status,Integer typeid, BigDecimal money) {
		QueryWrapper<Account> queryWrapper = new QueryWrapper<Account>();
		queryWrapper.eq("cid",cid);
		if(super.count(queryWrapper)<1) {
			return ResponseData.baseError("会员不存在");
		}else if(money==null) {
			return ResponseData.baseError("金额异常");
		}
		String accountDetail = insertAccountDetail(cid,typeid,status,money,HandleType.getName(typeid));
		if(ValidateUtil.empty(accountDetail)){
			return ResponseData.baseError(accountDetail);
		}
		return ResponseData.ok();
	}
	@Override
	public boolean handleDayMoney() {
		UpdateWrapper<Account> updateWrapper = new UpdateWrapper<Account>();
		Account account = new Account();
		account.setDayMoney(BigDecimal.ZERO);
		account.setSearchMoney(BigDecimal.ZERO);
		account.setMaxMoney(BigDecimal.ZERO);
		boolean update = super.update(account, updateWrapper);
		return update;
	}
	@Override
	public boolean handleMaxMoney(){
		List<Customer> list = customerService.list(new QueryWrapper<Customer>().eq("isopen", Constant.isOpen_success));
		Map<String, Goods> goodsMap = this.goodsService.listMap();
		for(Customer cus:list) {
			try {
				handleMaxMoney(cus,goodsMap);
			}catch(Exception e) {
				e.printStackTrace();
			}
		}
		return true;
	}

	private boolean handleMaxMoney(Customer cus,Map<String, Goods> goodsMap) {
		QueryWrapper<OrderGoods> queryWrapper = new QueryWrapper<OrderGoods>();
		queryWrapper.eq("cid", cus.getId());
		queryWrapper.gt("status",OrderStatusEnums.not.getId());
		List<OrderGoods> orderList = this.orderGoodsService.list(queryWrapper);
		Account account = this.get(cus.getId());
		for(OrderGoods order:orderList) {
			Goods goods = goodsMap.get(order.getGoodsCode());
			//判断是否是体验机
			if(ValidateUtil.isEquals(goods.getType(),1)) {
				 long day = DateUtil.between(order.getPaytime(), new Date(), DateUnit.DAY);
				 if(day>goods.getScanDay()) {//体验过期
					 continue;
				 }
			}
			BigDecimal dayProfit = FunctionUtils.mul(goods.getDayProfit(),new BigDecimal(order.getQty()),2);
			account.setMaxMoney(FunctionUtils.add(account.getMaxMoney(),dayProfit,2));
			account.setSearchMoney(account.getMaxMoney());
		}
		this.updateById(account);
		return true;
	}

}
